package com.kitty.game.fight.service;

import com.kitty.common.utils.SpringUtils;
import com.kitty.common.utils.Pair;
import com.kitty.common.core.SchedulerManager;
import com.kitty.game.ServerService;
import com.kitty.game.artifact.ArtifactService;
import com.kitty.game.chat.message.RespChat;
import com.kitty.game.chat.message.RespMessage;
import com.kitty.game.config.SpecialItem;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.enter.RespUpdate;
import com.kitty.game.equip.message.RespNotifyMiscEx;
import com.kitty.game.equip.model.EquipField;
import com.kitty.game.equip.model.RoleEquip;
import com.kitty.game.equip.service.EquipService;
import com.kitty.game.fight.bean.Fight;
import com.kitty.game.fight.bean.FightObject;
import com.kitty.game.fight.message.CombatStatus;
import com.kitty.game.fight.message.ReqFightDoAction;
import com.kitty.game.fight.message.RespAttackSkillLightEffect;
import com.kitty.game.fight.message.RespAutoFightSkill;
import com.kitty.game.fight.message.RespCharOffline;
import com.kitty.game.fight.message.RespCombatAcceptHit;
import com.kitty.game.fight.message.RespCombatAcceptMagicHit;
import com.kitty.game.fight.message.RespCombatAcceptMultiHit;
import com.kitty.game.fight.message.RespCombatAction;
import com.kitty.game.fight.message.RespCombatDied;
import com.kitty.game.fight.message.RespCombatEndAction;
import com.kitty.game.fight.message.RespCombatGodBookEffectSummon;
import com.kitty.game.fight.message.RespCombatLifeDelta;
import com.kitty.game.fight.message.RespCombatLightEffect;
import com.kitty.game.fight.message.RespCombatManaDelta;
import com.kitty.game.fight.message.RespCombatUpdate;
import com.kitty.game.fight.message.RespCombatUpdateImprovement;
import com.kitty.game.fight.message.RespCombatUpdateStatus;
import com.kitty.game.fight.message.RespCreateSequence;
import com.kitty.game.fight.message.RespCurrentRound;
import com.kitty.game.fight.message.RespFightClearTime;
import com.kitty.game.fight.message.RespFightCommandInfo;
import com.kitty.game.fight.message.RespFightFuhuo;
import com.kitty.game.fight.message.RespFightMianban;
import com.kitty.game.fight.message.RespFightShouting;
import com.kitty.game.fight.message.RespOpponentInfo;
import com.kitty.game.fight.message.RespQuitCombat;
import com.kitty.game.fight.message.RespRefreshPetList;
import com.kitty.game.fight.message.RespSelectCommand;
import com.kitty.game.fight.message.RespSetFightPetStatus;
import com.kitty.game.fight.message.RespStartCombat;
import com.kitty.game.fight.message.RespSyncMessage;
import com.kitty.game.fight.message.vo.MultiHit;
import com.kitty.game.fight.message.vo.OpponentInfo;
import com.kitty.game.fight.message.vo.RefreshPet;
import com.kitty.game.fight.message.vo.SkillGroup;
import com.kitty.game.fight.model.SkillAutoPicker;
import com.kitty.game.fight.task.FightingTask;
import com.kitty.game.fight.task.TimeOutTask;
import com.kitty.game.fight.util.FightAction;
import com.kitty.game.fight.util.FightMessageUtil;
import com.kitty.game.map.service.MapService;
import com.kitty.game.onlinemall.service.MallService;
import com.kitty.game.pet.message.RespPetInfo;
import com.kitty.game.pet.message.RespSetCurrentPet;
import com.kitty.game.pet.message.vo.PetInfo;
import com.kitty.game.pet.model.Pet;
import com.kitty.game.pet.service.PetService;
import com.kitty.game.role.model.Role;
import com.kitty.game.role.service.RoleService;
import com.kitty.game.shop.ShopDataPool;
import com.kitty.game.skill.model.RoleSkill;
import com.kitty.game.skill.service.SkillService;
import com.kitty.game.team.message.RespMsg;
import com.kitty.game.utils.*;
import com.kitty.mina.cache.DataCache;
import com.kitty.mina.cache.SessionUtils;
import com.kitty.mina.message.Message;
import com.kitty.mina.message.MessagePusher;
import org.apache.mina.core.session.IoSession;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ScheduledFuture;


import com.kitty.game.utils.AsktaoUtil;
import com.kitty.game.utils.BitSet;
import com.kitty.game.utils.FieldUtils;


import static com.kitty.game.utils.StatusConst.STATUS_IMMUNE_MAG_DAMAGE;

@Service
public class FightMessageService {
    private final Logger logger = LoggerFactory.getLogger(FightMessageService.class);

    @Autowired
    CountService countService;
    @Autowired
    SkillService skillService;
    @Autowired
    RoleService roleService;
    @Autowired
    PetService petService;
    @Autowired
    FightService fightService;
    @Autowired
    EquipService equipService;
    @Autowired
    ArtifactService artifactService;
    @Autowired
    ServerService serverService;


    public void sendFightAction(Fight fight, FightObject target) {
        if (target == null || target.isFallDown()) {
            return;
        }
        FightMessageUtil.sendFightPackage(fight, checkStatusStart(fight.getRound(), target));
        FightMessageUtil.sendFightPackage(fight, start(fight.getRound()));
        FightMessageUtil.sendFightPackage(fight, end());
        FightMessageUtil.sendFightPackage(fight, sendFightObjectStatus(target));
        FightMessageUtil.sendFightPackage(fight, doActionEnd(target.getId()));
    }

    public Message start(int round) {
        RespCombatAction respCombatAction = new RespCombatAction();
        respCombatAction.setRound((short) round);
        return respCombatAction;
    }

    public Message end() {
        return new RespCombatEndAction();
    }

    /**
     * 核心开始
     *
     * @param round
     * @param id
     * @return
     */
    public Message coreStart(int round, int id) {
        RespCombatAction respCombatAction = new RespCombatAction();
        respCombatAction.setAttacker_id(id);
        respCombatAction.setVictim_id(id);
        respCombatAction.setRound((short) round);
        return respCombatAction;
    }

    /**
     * 检测状态
     *
     * @param round
     * @param fightObject
     * @return
     */
    public Message checkStatusStart(int round, FightObject fightObject) {
        return checkStatusStart(round, fightObject.getId());
    }

    /**
     * 不做动作
     */
    public Message stayStart(int round, int id) {
        RespCombatAction respCombatAction = new RespCombatAction();
        respCombatAction.setAttacker_id(id);
        respCombatAction.setAction(FightAction.NULL);
        respCombatAction.setVictim_id(0);
        respCombatAction.setRound((short) round);
        respCombatAction.setSkillId(0);
        return respCombatAction;
    }

    /**
     * 检测状态
     */
    public Message checkStatusStart(int round, int id) {
        RespCombatAction respCombatAction = new RespCombatAction();
        respCombatAction.setAttacker_id(id);
        respCombatAction.setAction(FightAction.CHECK_STATUS);
        respCombatAction.setVictim_id(id);
        respCombatAction.setRound((short) round);
        respCombatAction.setSkillId(0);
        return respCombatAction;
    }

    /**
     * 做动作
     */
    public Message doActionStart(int round, FightObject fightObject) {
        RespCombatAction respCombatAction = new RespCombatAction();
        respCombatAction.setAttacker_id(fightObject.getId());
        respCombatAction.setAction((short) fightObject.getType());
        respCombatAction.setVictim_id(fightObject.getTargetId());
        respCombatAction.setRound((short) round);
        respCombatAction.setSkillId(fightObject.getSkillId());
        return respCombatAction;
    }

    /**
     * 法宝特效
     */
    public RespAttackSkillLightEffect attackSkillEffect(int id, short effectId, String name, int type) { //8013 翻天印
        RespAttackSkillLightEffect respAttackSkillLightEffect = new RespAttackSkillLightEffect();
        respAttackSkillLightEffect.setId(id);
        respAttackSkillLightEffect.setEffectId(effectId);
        respAttackSkillLightEffect.setName(name);
        respAttackSkillLightEffect.setType(type);//天书4 其他0
        return respAttackSkillLightEffect;
    }

    /**
     * 天书特效
     */
    public RespAttackSkillLightEffect bookSkillEffect(int id, String bookName) {
        return SpringUtils.getFightMessageService().attackSkillEffect(id, (short) 0,
                bookName, 4);
    }

    /**
     * 出手动画
     *
     * @param fightObject
     * @param targetAction
     * @param myAction
     * @param bookSkillId
     * @return
     */
    public Message combatAcceptHit(FightObject fightObject, int targetAction, int myAction, int bookSkillId) {
        RespCombatAcceptHit respCombatAcceptHit = new RespCombatAcceptHit();
        respCombatAcceptHit.setAttacker_id(fightObject.getId());
        respCombatAcceptHit.setVictim_id(fightObject.getTargetId());
        respCombatAcceptHit.setMissed((short) targetAction);//目标动作    0躲闪 1受伤动作
        respCombatAcceptHit.setDamage_type(myAction);//自己的动作
        respCombatAcceptHit.setPara((short) bookSkillId);
        return respCombatAcceptHit;
    }

    /**
     * @param targetId
     * @param lasLife
     * @return
     */
    public Message updateTargetLife(int targetId, int lasLife) {
        RespCombatUpdate respCombatUpdate = new RespCombatUpdate();
        respCombatUpdate.setId(targetId);
        ArrayList<FiedValue> list = new ArrayList<>();
        {
            FiedValue fiedValue = new FiedValue();
            fiedValue.setType((short) 6);//气血
            fiedValue.setVT((byte) 3);
            fiedValue.setValue(lasLife);
            list.add(fiedValue);
        }
        respCombatUpdate.setFiedValues(list);
        return respCombatUpdate;
    }

    public Message updateTargetMana(int targetId, int lastMana) {
        RespCombatUpdate respCombatUpdate = new RespCombatUpdate();
        respCombatUpdate.setId(targetId);
        ArrayList<FiedValue> list = new ArrayList<>();
        {
            FiedValue fiedValue = new FiedValue();
            fiedValue.setType((short) 11);//法力
            fiedValue.setVT((byte) 3);
            fiedValue.setValue(lastMana);
            list.add(fiedValue);
        }
        respCombatUpdate.setFiedValues(list);
        return respCombatUpdate;
    }

    public Message skillAction(Fight fight, int id, List<Integer> targetList, int myAction, boolean attack) {
        RespCombatAcceptMagicHit respCombatAcceptMagicHit = new RespCombatAcceptMagicHit();
        respCombatAcceptMagicHit.setHitterId(id);
        respCombatAcceptMagicHit.setDamageType(myAction);//34法术必杀
        if (attack) {
            List<Short> actionList = new ArrayList<>();
            for (Integer integer : targetList) {
                FightObject target = fight.queryFightObject(integer);
                if (target == null || target.isFallDown()) {
                    continue;
                }
                int tempDodge = target.getExtraDodge();
                if (target.isPlayer()) {
                    tempDodge += target.getRole().getDodge();
                }
                boolean isDodge = tempDodge >= new Random().nextInt(100) + 1;
                target.pushTempCache("dodge", isDodge);

                short action = 1;
                if (isDodge) {
                    action = 0;
                }
                if (target.isFrozen()) {
                    action = 2;//0躲闪 1正常受伤动作 2无动作
                }
                actionList.add(action);
            }
            respCombatAcceptMagicHit.setMissed(actionList);
        }
        respCombatAcceptMagicHit.setTargets(targetList);
        return respCombatAcceptMagicHit;
    }

    /**
     * 力魄动作
     */
    public Message liPoAction(Fight fight, int id, List<Integer> targetList, int myAction, int targetId) {
        RespCombatAcceptMultiHit respCombatAcceptMultiHit = new RespCombatAcceptMultiHit();
        respCombatAcceptMultiHit.setAttacker_id(id);
        respCombatAcceptMultiHit.setMainVictimId(targetId);
        respCombatAcceptMultiHit.setType(myAction);//34法术必杀 17连击
        List<MultiHit> targetInfos = new ArrayList<>();
        for (Integer integer : targetList) {
            MultiHit multiHit = new MultiHit();
            multiHit.setVictim_id(integer);
            FightObject target = fight.queryFightObject(integer);
            if (target == null || target.isFallDown()) {
                continue;
            }
            int tempDodge = target.getExtraDodge();
            if (target.isPlayer()) {
                tempDodge += target.getRole().getDodge();
            }
            boolean isDodge;
            if(targetId == integer){
               isDodge = target.getTempCache("dodge", false);
            }else{
                isDodge = tempDodge >= new Random().nextInt(100) + 1;
                target.pushTempCache("dodge", isDodge);
            }
            short action = 1;
            if (isDodge) {
                action = 0;
            }
            if (target.isFrozen()) {
                action = 2;
            }
            multiHit.setMissed(action);
            targetInfos.add(multiHit);
        }
        respCombatAcceptMultiHit.setTargets(targetInfos);
        return respCombatAcceptMultiHit;
    }

    /**
     * 战斗增益状态包
     */
    public Message fightExtra(FightObject fightObject, FightObject targetObject) {
        NutMap nutMap = targetObject.getStatusMap();
        RespCombatUpdateImprovement respCombatUpdateImprovement = new RespCombatUpdateImprovement();
        respCombatUpdateImprovement.setId(targetObject.getId());
        List<FiedValue> list = new ArrayList<>();
        respCombatUpdateImprovement.setList(list);
        if (fightObject.getPolar() == 1) {
            {
                FiedValue fiedValue = new FiedValue();
                list.add(fiedValue);
                fiedValue.setType((short) 3);//刀子
                fiedValue.setVT((byte) 3);
                fiedValue.setValue(nutMap.getInt(StatusConst.STATUS_PHY_POWER_UP + "value"));
            }
            {
                FiedValue fiedValue = new FiedValue();
                list.add(fiedValue);
                fiedValue.setType((short) 10);//法攻
                fiedValue.setVT((byte) 3);
                fiedValue.setValue(new Double(nutMap.getInt(StatusConst.STATUS_PHY_POWER_UP + "value") * 0.75).intValue());
            }
        } else if (fightObject.getPolar() == 3) {
            FiedValue fiedValue = new FiedValue();
            fiedValue.setType((short) 8);//防御
            fiedValue.setVT((byte) 3);
            fiedValue.setValue(nutMap.getInt(StatusConst.STATUS_DEF_UP + "value"));
            list.add(fiedValue);
        } else if (fightObject.getPolar() == 4) {
            FiedValue fiedValue = new FiedValue();
            fiedValue.setType((short) 14);//加速
            fiedValue.setVT((byte) 2);
            fiedValue.setValue(nutMap.getInt(StatusConst.STATUS_SPEED_UP + "value"));
            list.add(fiedValue);
        } else if (fightObject.getPolar() == 5) {
            FiedValue fiedValue = new FiedValue();
            fiedValue.setType((short) 15);//闪避
            fiedValue.setVT((byte) 3);
            fiedValue.setValue(nutMap.getInt(StatusConst.STATUS_DODGE_UP + "value"));
            list.add(fiedValue);
        }
        return respCombatUpdateImprovement;
    }



    /**
     * 掠阵宠物出战
     *
     * @必须是没有出战过的掠阵宠物才能参战
     */
    public Pair<Message, Message> supplyPetPackage(Fight fight, FightObject hostObject) {
        int supplyPetId = hostObject.getRole().getPetBox().getSupplyPetId();
        Pet pet = SpringUtils.getPetService().getPetById(supplyPetId, hostObject.getRole());
        RespRefreshPetList respRefreshPetList = new RespRefreshPetList();
        RefreshPet refreshPet = new RefreshPet();
        ArrayList<RefreshPet> refreshPets = new ArrayList<>();
        refreshPets.add(refreshPet);
        refreshPet.setPetId(pet.getId());
        respRefreshPetList.setPetList(refreshPets);
        MessagePusher.pushMessage(hostObject.getRole(), respRefreshPetList);

        RespSetFightPetStatus respSetFightPetStatus = new RespSetFightPetStatus();
        respSetFightPetStatus.setRoleId(pet.getId());
        respSetFightPetStatus.setType((short) 1);
        MessagePusher.pushMessage(hostObject.getRole(), respSetFightPetStatus);

        RespPetInfo respPetInfo = new RespPetInfo();
        ArrayList<EquipField> list = new ArrayList<>();
        PetInfo petInfo = new PetInfo();
        respPetInfo.setPetInfos(new ArrayList<>());
        respPetInfo.getPetInfos().add(petInfo);
        petInfo.setPosition(pet.getPosition());
        petInfo.setPetId(pet.getId());
        list.addAll(pet.getAllFields());
        byte[] body = AsktaoUtil.getMessageBody(respPetInfo);
        RespSyncMessage respSyncMessage = new RespSyncMessage();
        respSyncMessage.setCode((short) 65507);
        respSyncMessage.setMsg(body);
        MessagePusher.pushMessage(hostObject.getRole(), respSyncMessage);

        hostObject.setFightPetId(pet.getId());
        Pair<Message, Message> messages = fightService.addPet2Fight(hostObject.getId(), pet, fight, hostObject.getPos() + 5, true);

        RespSetCurrentPet respSetCurrentPet = new RespSetCurrentPet();
        respSetCurrentPet.setPetId(pet.getId());
        respSetCurrentPet.setStatus((short) 1);
        respSyncMessage = new RespSyncMessage();
        respSyncMessage.setCode((short) 4163);
        respSyncMessage.setMsg(AsktaoUtil.getMessageBody(respSetCurrentPet));
        MessagePusher.pushMessage(hostObject.getRole(), respSyncMessage);
        FightExecutorService.PETID_ROLEID.put(pet.getId(), pet.getHostId());
        FightExecutorService.FIGHT_ROOMS.put(pet.getId(), fight.getId());

        Map<String, Object> autoSet = pet.getAutoFightSet();
        if (autoSet == null || autoSet.size() == 0) {
            Map<String, Object> publicAutoSet = new HashMap<>();
            publicAutoSet.put("type", 1);
            publicAutoSet.put("action", 1);
            publicAutoSet.put("skillId", 0);
            publicAutoSet.put("multi", 0);
            publicAutoSet.put("list", new ArrayList<>());
            autoSet = publicAutoSet;
        }
        RespFightCommandInfo respFightCommandInfo = new RespFightCommandInfo();
        respFightCommandInfo.setId(pet.getId());
        respFightCommandInfo.setType(((Integer) autoSet.get("type")).shortValue());
        respFightCommandInfo.setSkillId((Integer) autoSet.get("skillId"));
        respFightCommandInfo.setMulti_index(((Integer) autoSet.get("multi")).byteValue());
        respFightCommandInfo.setAuto_select(((Integer) autoSet.get("action")).byteValue());
        respFightCommandInfo.setList((List<SkillGroup>) autoSet.get("list"));
        MessagePusher.pushMessage(hostObject.getRole(), respFightCommandInfo);

        return messages;
    }

    /**
     * 火眼显血包
     */
    public Message eyeInfo(List<FightObject> list) {
        RespOpponentInfo respOpponentInfo = new RespOpponentInfo();
        ArrayList<OpponentInfo> arrayList = new ArrayList<>();
        for (FightObject target : list) {
            OpponentInfo opponentInfo = new OpponentInfo();
            opponentInfo.setId(target.getId());
            ArrayList<FiedValue> fiedValues = new ArrayList<>();
            opponentInfo.setList(fiedValues);

            fiedValues.add(new FiedValue((short) 6, (byte) 3, target.getCurrLife()));
            fiedValues.add(new FiedValue((short) 7, (byte) 3, target.getMaxLife()));

            arrayList.add(opponentInfo);
        }
        respOpponentInfo.setList(arrayList);
        return respOpponentInfo;
    }

    /**
     * 清除火眼显血包
     */
    public Message clearEyeInfo() {
        return new RespOpponentInfo();
    }

    /**
     * 使用道具特效
     */
    public Message useItem(int id, int targetId, int useType) { // 1002 加血 1003 加蓝 6070火眼
        RespCombatLightEffect respCombatLightEffect = new RespCombatLightEffect();
        respCombatLightEffect.setType(useType);
        respCombatLightEffect.setHitter(id);
        respCombatLightEffect.setTarget(targetId);
        return respCombatLightEffect;
    }

    /**
     * 倒地
     *
     * @param id
     * @return
     */
    public Message fallDown(int id, int type) {
        RespCombatDied respCombatDied = new RespCombatDied(); //倒地
        respCombatDied.setId(id);
        respCombatDied.setType(type);
        return respCombatDied;
    }

    /**
     * 消失
     *
     * @return
     */
    public Message disappear(int id) {
        RespQuitCombat respQuitCombat = new RespQuitCombat();//消失
        respQuitCombat.setId(id);
        return respQuitCombat;
    }

    /**
     * 复活
     */
    public Message revive(int id) {
        RespFightFuhuo respFightFuhuo = new RespFightFuhuo();
        respFightFuhuo.setId(id);
        return respFightFuhuo;
    }

    public Message decreaseLife(int id, int targetId, int hurt, int type, int effectNo) {
        RespCombatLifeDelta respCombatLifeDelta = new RespCombatLifeDelta();
        respCombatLifeDelta.setAttacker_id(id);
        respCombatLifeDelta.setVictim_id(targetId);
        respCombatLifeDelta.setPoint(hurt);
        respCombatLifeDelta.setType(type);
        respCombatLifeDelta.setEffect_no(effectNo);
        return respCombatLifeDelta;
    }

    public Message createSequence(int id) {
        RespCreateSequence respCreateSequence = new RespCreateSequence();
        respCreateSequence.setId(id);
        return respCreateSequence;
    }

    /**
     * 掉蓝动画 舍命一击或魔引天书
     */
    public Message decreaseMana(int id, int targetId, int hurt, int effectNo) {
        RespCombatManaDelta manaDelta = new RespCombatManaDelta();
        manaDelta.setAttacker_id(id);
        manaDelta.setVictim_id(targetId);
        manaDelta.setPoint(-hurt);
        manaDelta.setEffect_no(effectNo);
        return manaDelta;
    }

    public RespCombatEndAction doActionEnd(int id) {
        RespCombatEndAction RespCombatEndAction = new RespCombatEndAction();
        RespCombatEndAction.setId(id);
        return RespCombatEndAction;
    }

    public Message summonPetBookEffect(int id, int icon) {
        RespCombatGodBookEffectSummon respCombatGodBookEffectSummon = new RespCombatGodBookEffectSummon();
        respCombatGodBookEffectSummon.setId(id);
        respCombatGodBookEffectSummon.setIcon((short) icon);
        return respCombatGodBookEffectSummon;
    }

    /**
     * 更新自己法力  只在使用物攻或者法攻时候更新
     */
    public Message updateObjectInfo(FightObject fightObject) {
        RespCombatUpdate respCombatUpdate = new RespCombatUpdate();
        respCombatUpdate.setId(fightObject.getId());
        ArrayList<FiedValue> list = new ArrayList<>();
        int mana = fightObject.getCurrMana();
        if (mana <= 0) {
            mana = 0;
        }
        fightObject.setCurrMana(mana);
        //气血
        list.add(new FiedValue((short) 6, (byte) 3, fightObject.getCurrLife()));
        //法力
        list.add(new FiedValue((short) 11, (byte) 3, mana));
        respCombatUpdate.setFiedValues(list);
        return respCombatUpdate;
    }

    /**
     * 自动战斗状态
     *
     * @param tempRole
     */
    public RespUpdate autoFightStatus(Role tempRole) {
        RespUpdate respUpdate = new RespUpdate();
        ArrayList<FiedValue> arrayList = new ArrayList<>();
        arrayList.add(new FiedValue(307, 1, tempRole.getAutoFight()));
        respUpdate.setRoleId(tempRole.getRoleId());
        respUpdate.setList(arrayList);
        return respUpdate;
    }

    /**
     * 战斗开始头
     */
    public RespStartCombat startCombat(Role role) {
        RespStartCombat respStartCombat = new RespStartCombat();
        respStartCombat.setMode((byte) 3);
        MapService mapService = SpringUtils.getBean(MapService.class);
        int type = mapService.roleInMapByType(role);
        respStartCombat.setPetCapcityType((byte)type);
        return respStartCombat;
    }
    public RespStartCombat startCombat() {
        RespStartCombat respStartCombat = new RespStartCombat();
        respStartCombat.setMode((byte)3);
        return respStartCombat;
    }

    public Message round(int round, int animateDone) {
        RespCurrentRound respCurrentRound = new RespCurrentRound();
        respCurrentRound.setRound((short) round);
        respCurrentRound.setAnimate_done((byte) animateDone);
        return respCurrentRound;
    }


    public Message mianban(int round) {
        RespFightMianban respFightMianban = new RespFightMianban();
        respFightMianban.setRound((short) round);
        Random random = new Random();
        int value = random.nextInt(260000000) + 40000000;
        respFightMianban.setQuestion(value);
        respFightMianban.setCurTime(new Long(System.currentTimeMillis() / 1000).intValue());
        return respFightMianban;
    }


    /**
     * 个人自动状态
     *
     * @param fightObject
     * @param fight
     * @return
     */
    public Message selfAuto(FightObject fightObject, Fight fight) {
        if (fightObject.getAutoFight() == 1) {
            try {
                RespAutoFightSkill respAutoFightSkill = new RespAutoFightSkill();
                SkillAutoPicker autoPicker = fightService.getAutoObject(fightObject, fight);
                respAutoFightSkill.setRoleSkillId(autoPicker.getSkillId());
                byte type = 0;
                if (autoPicker.isDef()) {
                    type = 1;
                } else {
                    if (autoPicker.getSkillId() == 2) {
                        type = 2;
                    } else if (SpringUtils.getArtifactService().isArtifactSkill(respAutoFightSkill.getRoleSkillId())) {
                        type = 16;
                    } else {
                        type = 3;
                    }
                }
                respAutoFightSkill.setUser_action(type);
                if (fightObject.getMultiIndex() == 1) {
                    respAutoFightSkill.setRoleIsGroup(true);
                    respAutoFightSkill.setRoleRound((byte) autoPicker.getLastRound());
                    respAutoFightSkill.setUser_next_action((byte) autoPicker.getNextType());
                    respAutoFightSkill.setRoleNextSkillId(autoPicker.getNextSkillId());
                }

                if (fightObject.getFightPetId() > 0) {
                    FightObject petObject = fight.queryFightObject(fightObject.getFightPetId());
                    if (petObject != null) {
                        byte petType = 0;
                        SkillAutoPicker petAutoPicker = fightService.getAutoObject(petObject, fight);
                        respAutoFightSkill.setPetSkillId(petAutoPicker.getSkillId());
                        if (petAutoPicker.isDef()) {
                            petType = 1;
                        } else {
                            if (petAutoPicker.getSkillId() == 2) {
                                petType = 2;
                            } else if (SpringUtils.getArtifactService().isArtifactSkill(respAutoFightSkill.getPetSkillId())) {
                                petType = 16;
                            } else {
                                petType = 3;
                            }
                        }
                        respAutoFightSkill.setPet_action(petType);
                        if (petObject.getMultiIndex() == 1) {
                            respAutoFightSkill.setPetIsGroup(true);
                            respAutoFightSkill.setPetRound((byte) petAutoPicker.getLastRound());
                            respAutoFightSkill.setPet_next_action((byte) petAutoPicker.getNextType());
                            respAutoFightSkill.setPetNextSkillId(petAutoPicker.getNextSkillId());
                        }
                    }
                }
                return respAutoFightSkill;
            } catch (Exception e) {
                logger.error("进战斗发送自动战斗状态报错==={}", Lang.getStackTrace(e));
            }
        }
        return null;
    }

    /**
     * 自动
     *
     * @param fight
     * @param fightObject
     * @return
     */
    public ReqFightDoAction autoFightOne(Fight fight, FightObject fightObject) {
        try{
            if (fight.isOver()) {
                return null;
            }
            IoSession session = fightObject.getSession();
            if (session == null) {
                ReqFightDoAction request = new ReqFightDoAction();
                request.setAttackerId(fightObject.getId());
                request.setType(2);// 物攻
                request.setSkillId(2);
                request.setTargetId(0);
                return request;
            }
            ReqFightDoAction request = new ReqFightDoAction();
            request.setAttackerId(fightObject.getId());
            SkillAutoPicker autoPicker = fightService.getAutoObject(fightObject, fight);
            request.setTargetId(autoPicker.getTargetId());
            request.setSkillId(autoPicker.getSkillId());
            if (autoPicker.isDef()) {
                request.setType(1);
                return request;//防御
            }
            if (request.getSkillId() == 2) {
                request.setType(2);// 物攻
                return request;
            }
            //下面法攻
            RoleSkill roleSkill = fightObject.getSkillBy(request.getSkillId());

            if (roleSkill == null) {
                request.setType(2);// 物攻
                request.setSkillId(2);
                return request;
            }
            if (SpringUtils.getArtifactService().isArtifactSkill(request.getSkillId())) {
                request.setType(16);
                return request;
            }
            if (fightObject.getCurrMana() >= roleSkill.getMana()) {//如果法力大于需要法力就是法攻
                request.setType(3);
                return request;
            }
            byte action = fightObject.getAction();//法力不足时 执行操作 1是自动加蓝 2是自动物攻
            if (action == 2) {
                request.setType(2);// 物攻
                request.setSkillId(2);
                return request;
            }
            //查找背包加蓝药品
            int pos = equipService.getManaMedicine("法玲珑", session);
            if (pos > 0) {//如果找到了法玲珑
                request.setSkillId(pos);
                request.setType(4);
                request.setTargetId(fightObject.getId());
                return request;
            }
            //如果设置了自动加蓝 但是背包找不到法玲珑
            Set<String> set = ShopDataPool.getRecoveMpMedicines();
            for (String string : set) {
                pos = equipService.getManaMedicine(string, session);
                if (pos >= 41) {//背包里面有
                    break;
                }
            }
            if (pos > 0) {//如果找到了药品
                request.setSkillId(pos);
                request.setType(4);
                request.setTargetId(fightObject.getId());
                return request;
            }
            MessagePusher.pushMessage(session, new RespNotifyMiscEx("当前包裹中没有补充法力药品，无法自动补充法力。"));
            request.setType(2);// 物攻
            request.setSkillId(2);
            request.setTargetId(0);
            return request;
        }catch (Exception e){
           // LoggerUtils.error("定时战斗报错={}",e);
            ReqFightDoAction request = new ReqFightDoAction();
            request.setAttackerId(fightObject.getId());
            request.setType(1);// 防御
            request.setSkillId(0);
            request.setTargetId(fightObject.getId());
            return request;
        }

    }

    public Message fightAction(FightObject fightObject) {
        if (fightObject == null) {
            return null;
        }
        IoSession session = fightObject.getSession();
        if (session == null) return null;
        Role role = SessionUtils.getRoleBySession(session);
        RespSelectCommand respSelectCommand = new RespSelectCommand();
        respSelectCommand.setAttacker_id(fightObject.getId());
        respSelectCommand.setVictim_id(fightObject.getTargetId());
        respSelectCommand.setAction((byte) fightObject.getType());
        int icon = 0;
        if (fightObject.getType() == 4) {//使用道具 找出道具图标
            RoleEquip roleEquip = equipService.getRoleEquipByPos(role, fightObject.getSkillId());
            if (roleEquip != null) {
                SpecialItem specialItem = SpringUtils.getBean(MallService.class).getSpecialItem(roleEquip.getName());
                if (specialItem != null) {
                    icon = specialItem.getIcon();
                }
            }
        } else if (fightObject.getType() == 3 || fightObject.getType() == 16) {
            icon = fightObject.getSkillId();
        }
        respSelectCommand.setSkillId(icon);
        if (fightObject.getType() == 4 && icon == 0) {
            return null;
        }
        return respSelectCommand;
    }

    public Message clearClock(int id) {
        RespFightClearTime respFightClearTime = new RespFightClearTime();
        respFightClearTime.setRoleId(id);
        respFightClearTime.setIsClear((byte) 0);//出手完之后消除头顶时钟 如果有宠物 需要判断宠物是否出手
        return respFightClearTime;
    }


    public ArrayList<Message> getStatusMessages(FightObject fightObject) {
        boolean poison = fightObject.getTempCache("poison", false);
        boolean recover = fightObject.getTempCache("recover", false);
        boolean dead = fightObject.getTempCache("dead", false);
        boolean alive = fightObject.getTempCache("alive", false);
        boolean poisonDead = fightObject.getTempCache("poisonDead", false);
        boolean revive = fightObject.getTempCache("revive", false);
        int poisonValue = fightObject.getTempCache("poisonValue", 0);
        int recoverLife = fightObject.getTempCache("recoverLife", 0);

        ArrayList<Message> arrayList = new ArrayList<>();
        if (recover || poison) {
            arrayList.add(updateTargetLife(fightObject.getId(), fightObject.getCurrLife()));
        }
        // 心的加血动画
        if (recover) {
            arrayList.add(decreaseLife(fightObject.getId(), fightObject.getId(), recoverLife, 4098, 10005));
            if (dead) {
                arrayList.add(revive(fightObject.getId()));
            }
        }
        // 毒的掉血动画
        if (poison && alive) {
            arrayList.add(decreaseLife(fightObject.getId(), fightObject.getId(), -poisonValue, 4098, 0));
            if (poisonDead) {
                arrayList.add(fallDown(fightObject.getId(), 4098));
                if (fightObject.isMonster()) {
                    arrayList.add(disappear(fightObject.getId()));
                } else if (fightObject.isPet()) {
                    if (revive) {
                        arrayList.add(revive(fightObject.getId()));
                        arrayList.add(petRelieveShouting(fightObject.getPet()));
                        arrayList.add(updateTargetLife(fightObject.getId(), fightObject.getCurrLife()));
                    } else {
                        arrayList.add(disappear(fightObject.getId()));
                    }
                }
            }
        }
        return arrayList;
    }

    @Autowired
    FightExecutorService fightExecutorService;

    public void sendPanel(Fight fight) {
        fightExecutorService.addFightTask(fight, new FightingTask() {
            @Override
            public void run() {
                fight.cancelTask(fight.getTimeOutTask());

                TimeOutTask timeOut = new TimeOutTask(fight.getId());
                ScheduledFuture<?> timeOutTask = SchedulerManager.getInstance().schedule(timeOut, 24500);
                fight.setTimeOutTask(timeOutTask);
            }
        });

        if (fight.getType() == Const.fightType_PK){
            for (FightObject fightObject : fight.getAllFightObjects()) {
                if (!fightObject.isDoAction()) {
                    if (fightObject.isPlayer()) {
                        fightService.autoFightOne(fight, fightObject);
                    }
                }
            }
        }

        // 自动托管  自动战斗
        for (FightObject fightObject : fight.getAllFightObjects()) {
            if (!fightObject.isDoAction()) {
                if (fightObject.isPlayer()) {
                    Role role = DataCache.ONLINE_ROLES_lixian.get(fightObject.getRole().getUid()) ;
                    if(role!=null){
                        if(role.getExtendBox().getTuoguanstate()==1){
                            fightService.autoFightOne(fight, fightObject);
                        }
                    }
                }
            }
        }


    }


    public void sendPanel(FightObject fightObject, Fight fight) {
        IoSession session = fightObject.getSession();
        if (!fightObject.isDoAction()) {
            if (fightObject.isPlayer()) {
                MessagePusher.pushMessage(session, round(fight.getRound(), 0));
                MessagePusher.pushMessage(session, mianban(fight.getRound()));
                MessagePusher.pushMessage(session, selfAuto(fightObject, fight));
                fightService.autoFightOne(fight, fightObject);
            }
        }
    }

    /**
     * 战斗喊话
     *
     * @param fightObject
     * @param msg
     * @return
     */
    public Message fightMsg(FightObject fightObject, String msg) {
        Role newRole = new Role();
        newRole.setRoleIcon((short) fightObject.getIcon());
        newRole.setLevel(fightObject.getLevel());
        RespSyncMessage respSyncMessage = new RespSyncMessage();
        RespChat respChat = new RespChat();
        respChat.setMsg(msg);
        respChat.setList(FieldUtils.getChatList(newRole));
        respChat.setRoleName(fightObject.getName());
        respChat.setLineName(serverService.getServer().getSonName());
        respChat.setRoleId(fightObject.getId());
        respChat.setType(ChatConst.CURRENT);
        respChat.setTime(new Long(new Date().getTime() / 1000).intValue());
        respSyncMessage.setCode((short) 16383);
        respSyncMessage.setMsg(AsktaoUtil.getMessageBody(respChat));
        return respSyncMessage;
    }
    /**
     * 战斗喊话
     *
     * @param fightObject
     * @param msg
     * @return
     */
    public Message fightToMsg(FightObject fightObject, String msg) {
        Role newRole = new Role();
        newRole.setRoleIcon((short) fightObject.getIcon());
        newRole.setLevel(fightObject.getLevel());
        RespChat respChat = new RespChat();
        respChat.setMsg(msg);
        respChat.setList(FieldUtils.getChatList(newRole));
        respChat.setRoleName(fightObject.getName());
        respChat.setLineName(serverService.getServer().getSonName());
        respChat.setRoleId(fightObject.getId());
        respChat.setType(ChatConst.CURRENT);
        respChat.setTime(new Long(new Date().getTime() / 1000).intValue());
        return respChat;
    }


    /**
     * 战斗自动喊话
     */
    public Message fightShouting(FightObject fightObject, String type) {
        try {
            if (fightObject == null) {
                return null;
            }
            List<NutMap> fightMsg = fightObject.getFightMsg();
            if (fightMsg == null || fightMsg.size() <= 0) {
                return null;
            }
            Role role = fightObject.getRole();
            if (role == null) {
                role = SessionUtils.getRoleBySession(fightObject.getSession());
                if (role == null) {
                    return null;
                }
            }
            if (role.getExtendBox().getSetMap().getOrDefault("combat_auto_talk", 0) == 0) {// 关闭喊话
                return null;
            }
            int id = fightObject.getId();
            String content = null;
            switch (type) {
                case "出战": // Todo 召唤宠物 ,或者宠物掠阵
                    for (NutMap nutMap : fightMsg) {
                        if (nutMap.getInt("type") == 7) {
                            content = nutMap.getString("msg");
                        }
                    }
                    if (!Strings.isEmpty(content)) {
                        RespMessage respMessage = new RespMessage();
                        respMessage.setLineName(serverService.getServer().getSonName());
                        respMessage.setMsg(content);
                        respMessage.setId(id);
                        respMessage.setTypeName(fightObject.getName());
                        respMessage.setTime(new Long(new Date().getTime() / 1000).intValue());
                        respMessage.setChannel((short) 17);
                        respMessage.setShow_time((byte) 2);
                        respMessage.setIcon((short) fightObject.getIcon());
                        RespSyncMessage respSyncMessage = new RespSyncMessage();
                        respSyncMessage.setCode((short) 12287);
                        respSyncMessage.setMsg(AsktaoUtil.getMessageBody(respMessage));
                        return respSyncMessage;
                    }
                    return null;
                case "物攻": // 物攻
                    for (NutMap nutMap : fightMsg) {
                        if (nutMap.getInt("type") == 1) {
                            content = nutMap.getString("msg");
                        }
                    }
                    break;
                case "防御": // 防御
                    for (NutMap nutMap : fightMsg) {
                        if (nutMap.getInt("type") == 2) {
                            content = nutMap.getString("msg");
                        }
                    }
                    break;
                case "法攻":
                    int skillId = fightObject.getSkillId();
                    for (NutMap nutMap : fightMsg) {
                        if (nutMap.getInt("para") == skillId) {
                            content = nutMap.getString("msg");
                        }
                    }
                    break;
            }
            if (Strings.isEmpty(content)) {
                return null;
            }
            RespFightShouting respFightShouting = new RespFightShouting();
            respFightShouting.setId(id);
            respFightShouting.setLineName(serverService.getServer().getSonName());
            respFightShouting.setMsg(content);
            return respFightShouting;
        } catch (Exception e) {
            //LoggerUtils.error("", e);
            return null;
        }
    }


    /**
     * 宠物复活喊话
     *
     * @param pet
     * @param pet
     */
    public Message petRelieveShouting(Pet pet) {
        Role role = SpringUtils.getRoleService().getOnlinePlayer(pet.getHostId());

        String[] msgs = {"主人不要为我担心，凭他们的三脚猫的功夫，是杀不死我的！", "都说猫有九条命，可是我有十条命哟！他们是打不死我的！", "还好没打中我的要害，看来我要把压箱底的功夫使出来了！"};
        Random random = new Random();
        int index = random.nextInt(msgs.length);
        RespMessage respMessage = new RespMessage();
        respMessage.setLineName(serverService.getServer().getSonName());
        respMessage.setMsg(msgs[index]);
        respMessage.setId(pet.getId());
        respMessage.setTypeName(pet.getName());
        respMessage.setTime(new Long(new Date().getTime() / 1000).intValue());
        respMessage.setChannel(ChatConst.CURRENT);
        respMessage.setIcon(pet.getIcon());
        RespSyncMessage respSyncMessage = new RespSyncMessage();
        RespMsg msg = new RespMsg("由于#Y" + pet.getName() + "#n和你的亲密度影响，#Y" + pet.getName() + "#n复活了。");
        respSyncMessage.setCode((short) 8165);
        respSyncMessage.setMsg(AsktaoUtil.getMessageBody(msg));
        MessagePusher.pushMessage(role, respSyncMessage);

        respSyncMessage = new RespSyncMessage();
        respSyncMessage.setCode((short) 12287);
        respSyncMessage.setMsg(AsktaoUtil.getMessageBody(respMessage));
        return respSyncMessage;
    }

    /**
     * 更新战场对象的状态
     */
    public Message sendFightObjectStatus(FightObject fightObject) {
        RespCombatUpdateStatus res = new RespCombatUpdateStatus();
        res.setTargetId(fightObject.getId());
        res.setParam(new ArrayList<>());
        BitSet first = BitSet.NEW();
        BitSet second = BitSet.NEW();
        BitSet third = BitSet.NEW();
        NutMap statusMap = fightObject.getStatusMap();
        statusMap.forEach((key, value) -> {
            if (!key.contains("value")) {/**不能把value的key值转int*/
                if (Integer.parseInt(key) <= STATUS_IMMUNE_MAG_DAMAGE) {
                    if ((int) value > 0) {
                        first.setBit(Integer.parseInt(key), true);
                    }
                } else if(Integer.parseInt(key) <= StatusConst.STATUS_DLB_BJ) {
                    if ((int) value > 0) {
                        second.setBit(Integer.parseInt(key), true);
                    }
                }else {
                    if ((int) value > 0) {
                        third.setBit(Integer.parseInt(key), true);
                    }
                }
            }
        });
        res.getParam().add(first.getI32());
        res.getParam().add(second.getI32());
        res.getParam().add(third.getI32());
        return res;
    }


    /**
     * 重连检测状态
     */
    public CombatStatus checkCombatStatus(FightObject fightObject) {
        CombatStatus res = new CombatStatus();
        res.setTargetId(fightObject.getId());
        res.setParam(new ArrayList<>());
        BitSet first = BitSet.NEW();
        BitSet second = BitSet.NEW();
        BitSet third = BitSet.NEW();

        NutMap statusMap = fightObject.getStatusMap();
        statusMap.forEach((key, value) -> {
            if (!key.contains("value")) {/**不能把value的key值转int*/
                if (Integer.parseInt(key) <= STATUS_IMMUNE_MAG_DAMAGE) {
                    if ((int) value > 0) {
                        first.setBit(Integer.parseInt(key), true);
                    }
                } else if(Integer.parseInt(key) <= StatusConst.STATUS_DLB_BJ) {
                    if ((int) value > 0) {
                        second.setBit(Integer.parseInt(key), true);
                    }
                }else {
                    if ((int) value > 0) {
                        third.setBit(Integer.parseInt(key), true);
                    }
                }
            }
        });
        res.getParam().add(first.getI32());
        res.getParam().add(second.getI32());
        res.getParam().add(third.getI32());
        if (fightObject.isFallDown()) {
            res.setIsDie((short) 1);
        }
        return res;
    }

    public Message charOffline(int roleId, int offOnline) {
        return new RespCharOffline(roleId, offOnline);
    }

    /**
     * 不做动作
     */
    public void sendNullAction(Fight fight, FightObject fightObject) {
        FightMessageUtil.sendFightPackage(fight, stayStart(fight.getRound(), fightObject.getId()));
        FightMessageUtil.sendFightPackage(fight, doActionEnd(fightObject.getId()));
    }
}
